home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 3D / RaveContextSample / Source / 3DMF.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  8.4 KB  |  387 lines  |  [TEXT/MPCC]

  1. /****************************/
  2. /*       3DMF.C                    */
  3. /****************************/
  4.  
  5.  
  6. /****************************/
  7. /*    EXTERNALS             */
  8. /****************************/
  9. #include <Script.h>
  10.  
  11. #include <QD3D.h>
  12. #include <QD3DGroup.h>
  13. #include <QD3DStorage.h>
  14. #include <QD3DIO.h>
  15. #include <QD3DErrors.h>
  16.  
  17. #include "myglobals.h"
  18. #include "misc.h"
  19. #include "3dmf.h"
  20. #include "process.h"
  21.  
  22.  
  23. /****************************/
  24. /*    PROTOTYPES            */
  25. /****************************/
  26.  
  27. static TQ3Status     MyRead3DMFModel(TQ3FileObject file, TQ3Object *model, TQ3Object *viewHints);
  28. static Boolean         Get3DMFInputFileName(FSSpec *myFSSpec);
  29. static TQ3FileObject Create3DMFFileObject(FSSpec *myFSSpec);
  30. static Boolean         Get3DMFOutputFileName(FSSpec *myFSSpec);
  31.  
  32.  
  33.  
  34. /****************************/
  35. /*    CONSTANTS             */
  36. /****************************/
  37.  
  38.  
  39. /*********************/
  40. /*    VARIABLES      */
  41. /*********************/
  42.  
  43. FSSpec    gLast3DMF_FSSpec;
  44.  
  45. long    gTotalNumVertecies,gTotalNumFaces,gTotalMeshes;
  46.  
  47.  
  48. /*************** LOAD 3DMF MODEL **************/
  49. //
  50. // INPUT: inFile = nil if use Standard File Dialog, else FSSpec of file to load
  51. //
  52. // OUTPUT: nil = didnt happen
  53. //
  54.  
  55. TQ3Object    Load3DMFModel(FSSpec *inFile)
  56. {
  57. TQ3FileObject        fileObj;
  58. TQ3Object            theModel,viewHints;
  59. FSSpec                myFSSpec;
  60.  
  61.                 /* INIT SOME STUFF */
  62.                 
  63.     gTotalNumVertecies = gTotalNumFaces = gTotalMeshes = 0;
  64.  
  65.  
  66.     if (inFile == nil)                                        // see if need to let user choose file
  67.     {
  68.             /* SELECT FILE TO OPEN */
  69.             
  70.         if (!Get3DMFInputFileName(&myFSSpec))
  71.             return(nil);
  72.     }
  73.     else
  74.         myFSSpec = *inFile;                                    // use input FSSpec
  75.         
  76.     gLast3DMF_FSSpec = myFSSpec;                            // also keep a global copy
  77.  
  78.             /* CREATE A FILE OBJECT */
  79.                 
  80.     fileObj = Create3DMFFileObject(&myFSSpec);
  81.     if (fileObj == nil)
  82.         theModel = nil;
  83.     else
  84.     {
  85.  
  86.             /* READ THE 3DMF FILE */
  87.             
  88.         if (MyRead3DMFModel(fileObj, &theModel, &viewHints) == kQ3Failure)
  89.             theModel = nil;
  90.     }
  91.     
  92.     Q3Object_Dispose(fileObj);
  93.  
  94.  
  95.     return(theModel);
  96. }
  97.  
  98.  
  99. /*************** CREATE 3DMF FILE OBJECT ****************/
  100. //
  101. // Creates and returns a File Object which contains the 3DMF file.
  102. //
  103. // INPUT: myFSSpec = file to create object for
  104. //
  105.  
  106. static TQ3FileObject    Create3DMFFileObject(FSSpec *myFSSpec)
  107. {
  108. TQ3FileObject        myFileObj;
  109. TQ3StorageObject    myStorageObj;
  110.         
  111.         /* CREATE NEW STORAGE OBJECT WHICH IS THE 3DMF FILE */
  112.             
  113.     myStorageObj = Q3FSSpecStorage_New(myFSSpec);
  114.     if (myStorageObj == nil)
  115.     {
  116.         DoFatalAlert("\pError calling Q3FSSpecStorage_New");
  117.         return(nil);
  118.     }
  119.     
  120.     
  121.             /* CREATE NEW FILE OBJECT */
  122.             
  123.     myFileObj = Q3File_New();
  124.     if (myFileObj == nil)
  125.     {
  126.         DoFatalAlert("\pError calling Q3File_New");
  127.         Q3Object_Dispose(myStorageObj);
  128.         return(nil);
  129.     }
  130.     
  131.             /* SET THE STORAGE FOR THE FILE OBJECT */
  132.             
  133.     if (Q3File_SetStorage(myFileObj, myStorageObj) != kQ3Success)
  134.     {
  135.         DoAlert("\pError Q3File_SetStorage");
  136.         return(nil);
  137.     }
  138.     Q3Object_Dispose(myStorageObj);
  139.             
  140.     return(myFileObj);
  141. }
  142.  
  143.  
  144. /******************* GET 3DMF INPUT FILE NAME ********************/
  145. //
  146. // Does Standard File IO and returns a filled in FSSpec record for selected 3DMF file.
  147. //
  148. // OUTPUT: false = error occurred
  149. //            FSSpec = file info
  150. //
  151.  
  152. static Boolean Get3DMFInputFileName(FSSpec *myFSSpec)
  153. {
  154. StandardFileReply    reply;
  155. SFTypeList    typeList;
  156. short        numTypes;
  157.  
  158.     typeList[0] = '3DMF';
  159.     typeList[1] = 'TEXT';
  160.     numTypes = 2;
  161.         
  162.     StandardGetFile(nil,numTypes,typeList,&reply);
  163.     if (!reply.sfGood)                                // see if cancelled 
  164.         return(false);
  165.  
  166.     *myFSSpec = reply.sfFile;                        // copy FSSpec back
  167.     return(true);
  168. }
  169.  
  170.  
  171.  
  172. /***************** READ 3DMF MODEL ************************/
  173. //
  174. // Reads the 3DMF file and saves into new TQ3Object.
  175. //
  176. // INPUT:  file = File Object containing reference to 3DMF file
  177. //
  178. // OUTPUT: model =object containing all the important data in the 3DMF file
  179. //           viewHints = object containing all viewHints objects???
  180. //
  181. //
  182.  
  183. static TQ3Status MyRead3DMFModel(TQ3FileObject file, TQ3Object *model, TQ3Object *viewHints)
  184. {
  185. TQ3GroupObject    myGroup;
  186. TQ3Object        myObject;
  187.  
  188.         /* INIT VIEW HINTS & MODEL TO BE RETURNED */
  189.         
  190.     *viewHints = *model = nil;                                            // assume return nothing
  191.     myGroup = myObject = nil;
  192.     
  193.         /* OPEN THE FILE OBJECT & EXIT GRACEFULLY IF UNSUCCESSFUL */
  194.  
  195.     if (Q3File_OpenRead(file,nil) != kQ3Success)                            // open the file
  196.     {
  197.         DoFatalAlert("\pReading 3DMF file failed!");
  198.         return    kQ3Failure;
  199.     }
  200.     
  201.     do
  202.     {
  203.         myObject = nil;
  204.         
  205.             /* READ A METAFILE OBJECT FROM THE FILE OBJECT */
  206.  
  207.         myObject = Q3File_ReadObject(file);
  208.         if (myObject == nil)
  209.         {
  210.         
  211.             if (myGroup)
  212.                 Q3Object_Dispose(myGroup);
  213.  
  214.             QD3D_ShowError("\pReading returned NULL object!", true);
  215.             break;
  216.         }
  217.                         
  218.         /* SAVE A VIEW HINTS OBJECT & ADD ANY DRAWABLE OBJECTS TO A GROUP */
  219.         
  220.         if (Q3Object_IsType(myObject, kQ3SharedTypeViewHints))            // see if is a View Hint object
  221.         {
  222.             if (*viewHints == nil)
  223.             {
  224.                 *viewHints = myObject;
  225.                 myObject = NULL;
  226.             }
  227.         }
  228.         else
  229.         if (Q3Object_IsDrawable(myObject))                                // see if is a drawable object
  230.         {
  231.             if (myGroup)                                                // if group exists
  232.             {
  233.                 Q3Group_AddObject(myGroup,myObject);                    // add object to group
  234.             }
  235.             else
  236.             if (*model == nil)                                            // if no model data yet
  237.             {
  238.                 *model = myObject;                                        // set model to this object
  239.                 myObject = nil;                                            // clear this object
  240.             }
  241.             else
  242.             {
  243.                 myGroup = Q3DisplayGroup_New();                            // make new group
  244.                 Q3Group_AddObject(myGroup,*model);                        // add existing model to group
  245.                 Q3Group_AddObject(myGroup,myObject);                    // add object to group
  246.                 Q3Object_Dispose(*model);                                // dispose model
  247.                 *model = myGroup;                                        // set return value to the new group
  248.             }
  249.         }
  250.         
  251.         if (myObject != nil)
  252.             Q3Object_Dispose(myObject);
  253.     } while(!Q3File_IsEndOfFile(file));
  254.     
  255.     if (Q3Error_Get(nil) != kQ3ErrorNone)
  256.     {
  257.         if (*model != nil)
  258.         {
  259.             Q3Object_Dispose(*model);
  260.             *model = nil;
  261.         }
  262.         
  263.         if (*viewHints != nil)
  264.         {
  265.             Q3Object_Dispose(*viewHints);
  266.             *viewHints = nil;
  267.         }
  268.         return(kQ3Failure);
  269.     }
  270.     return(kQ3Success);
  271. }
  272.     
  273.  
  274. /*************** SAVE 3DMF MODEL **************/
  275. //
  276. // INPUT: outFile = nil if use Standard File Dialog, else FSSpec of file to load
  277. //
  278. //
  279.  
  280. void Save3DMFModel(QD3DSetupOutputType *setupInfo,FSSpec *outFile, void (*callBack)(QD3DSetupOutputType *))
  281. {
  282. TQ3FileObject        fileObj;
  283. TQ3Object            theModel;
  284. FSSpec                myFSSpec;
  285. TQ3Status                myStatus;
  286. TQ3ViewStatus            myViewStatus;
  287. TQ3FileMode            fileMode;
  288.  
  289. #if DEMO_VERSION
  290.     DoAlert("\pSorry, the demo version of 3DMF Optimizer cannot save files, but the optimized model will now be displayed in the Model Window.");
  291. #else
  292.  
  293.     if (outFile == nil)                                        // see if need to let user choose file
  294.     {
  295.             /* SELECT FILE TO OPEN */
  296.             
  297.         if (!Get3DMFOutputFileName(&myFSSpec))
  298.             return;
  299.     }
  300.     else
  301.     {
  302.         myFSSpec = *outFile;                                // use input FSSpec    
  303.         FSpDelete(&myFSSpec);                                // delete any old one
  304.         FSpCreate(&myFSSpec, 'OP20', '3DMF', smSystemScript);        // create new file
  305.     }
  306.     
  307.     gLast3DMF_FSSpec = myFSSpec;                            // also keep a global copy
  308.  
  309.             /* CREATE A FILE OBJECT */
  310.                 
  311.     fileObj = Create3DMFFileObject(&myFSSpec);
  312.     if (fileObj == nil)
  313.         theModel = nil;
  314.     else
  315.     {
  316.                                             // set binary or text output
  317.         fileMode = kQ3FileModeNormal;
  318. //        fileMode = kQ3FileModeText;
  319.             
  320.         myStatus = Q3File_OpenWrite(fileObj, fileMode);
  321.         if ( myStatus != kQ3Success )
  322.             DoFatalAlert("\pQ3File_OpenWrite Failed!");
  323.     
  324.             /* WRITE THE 3DMF FILE */
  325.             
  326.                 
  327.         myStatus = Q3View_StartWriting(setupInfo->viewObject,fileObj);            
  328.         if ( myStatus != kQ3Success )
  329.             DoFatalAlert("\pQ3View_StartWriting Failed!");
  330.         
  331.                 /***************/
  332.                 /* SUBMIT LOOP */
  333.                 /***************/
  334.         do
  335.         {
  336.     
  337.                 /* CALL INPUT WRITE FUNCTION */
  338.     
  339.             callBack(setupInfo);
  340.     
  341.             myViewStatus = Q3View_EndWriting(setupInfo->viewObject);
  342.         } while ( myViewStatus == kQ3ViewStatusRetraverse );            
  343.     }
  344.     
  345.     myStatus = Q3File_Close(fileObj);
  346.     if ( myStatus == kQ3Failure )
  347.         DoFatalAlert("\pQ3File_Close Failed!");
  348.  
  349.     Q3Object_Dispose(fileObj);
  350.  
  351. #endif
  352. }
  353.     
  354.     
  355.     
  356. /******************* GET 3DMF OUTPUT FILE NAME ********************/
  357. //
  358. // Does Standard File IO and returns a filled in FSSpec record for selected 3DMF file & creates the file!
  359. //
  360. // OUTPUT: false = error occurred
  361. //            FSSpec = file info
  362. //
  363.  
  364. static Boolean Get3DMFOutputFileName(FSSpec *myFSSpec)
  365. {
  366. StandardFileReply    reply;
  367.     
  368.         
  369.     StandardPutFile("\pSave 3DMF file",gLast3DMF_FSSpec.name,&reply);
  370.     if (!reply.sfGood)                                // see if cancelled 
  371.         return(false);
  372.  
  373.     *myFSSpec = reply.sfFile;                        // copy FSSpec back
  374.     
  375.     if (reply.sfReplacing)
  376.         FSpDelete(myFSSpec);                                    // delete any old one
  377.     FSpCreate(myFSSpec, 'OP20', '3DMF', smSystemScript);        // create new file
  378.     
  379.     return(true);
  380. }
  381.  
  382.     
  383.     
  384.     
  385.     
  386.     
  387.